class System

  # Attributes
  attr_reader :mfc_class_name
  attr_reader :mfc_class_schema

  attr_accessor :rect	
  attr_reader :position_spacing
  attr_reader :rhythslash_spacing_above
  attr_reader :rhythslash_spacing_below
  attr_reader :extra_spacing
  attr_reader :start_bar
  attr_reader :end_bar

  # Constants
  DEFAULT_RECT = [ 0, 0, 0, 0 ]
  DEFAULT_POSITION_SPACING = 20
  DEFAULT_RHYTHM_SLASH_SPACING_ABOVE = 0
  DEFAULT_RHYTHM_SLASH_SPACING_BELOW = 0
  DEFAULT_EXTRA_SPACING = 0
   
  # Constructor
  def initialize()

    mfc_class_name = "CSection"
    mfc_class_schema = 1

    @rect = [ 50, 20, 800, 143 ]
    @position_spacing = DEFAULT_POSITION_SPACING
    @rhythslash_spacing_above = DEFAULT_RHYTHM_SLASH_SPACING_ABOVE
    @rhythslash_spacing_below = DEFAULT_RHYTHM_SLASH_SPACING_BELOW
    @extra_spacing = DEFAULT_EXTRA_SPACING
   
    @start_bar = Barline.new 
    @direction_array = [ ]
    @chord_text_array = [ ]
    @rhythslash_array = [ ]
    @staff_array = [ ]
    @barline_array = [ ]
    @end_bar = Barline.new    
    @staff_array[0] = Staff.new
     
  end
   
  # Methods       
  def valid_direction_index?(index)
    return (index < direction_count())
  end
   
  def direction_count
    return @direction_array.size
  end
   
  def direction(index)
    return nil unless valid_direction_index?(index)
    return @direction_array[index]
  end
   
  def valid_chord_text_index?(index)
    return (index < chord_text_count())
  end
   
  def chord_text_count
    return @chord_text_array.size
  end
   
  def chord_text(index)
    return nil unless valid_chord_text_index?(index)
    return @chord_text_array[index]
  end
   
  def valid_rhythslash_index?(index)
    return (index < rhythslash_count())
  end
   
  def rhythslash_count
    return @rhythslash_array.size
  end
   
  def rhythslash(index)
    return nil unless valid_rhythslash_index?(index)
    return @rhythslash_array[index]
  end
   
  def valid_staff_index?(index)
    return (index < staff_count())
  end
   
  def staff_count
    return @staff_array.size
  end
   
  def staff(index)
    return nil unless valid_staff_index?(index)
    return @staff_array[index]
  end
   
  def valid_barline_index?(index)
    return (index < barline_count())
  end
   
  def barline_count
    return @barline_array.size
  end
   
  def barline(index)
    return nil unless valid_barline_index?(index)
    return @barline_array[index]
  end
   
  def barline_at_position(position)
    if (position == 0)
      return @start_bar
    end
     
    barline_count.times do |barline_index|       
      barline = barline(barline_index)
      if (barline.position == position)
        return (barline)
      end
    end
     
    return nil
  end   
   
  # Serialization
  def do_serialize(stream)
    write_mfc_rect(stream, @rect)
    end_bar = ((@end_bar.type << 5) | (@end_bar.repeat_count))
    write_byte(stream, end_bar)
    write_byte(stream, @position_spacing)
    write_byte(stream, @rhythslash_spacing_above)
    write_byte(stream, @rhythslash_spacing_below)
    write_byte(stream, @extra_spacing)    
    @start_bar.do_serialize(stream)
    arr = PowerTabArray.new
    arr.do_serialize(stream, @direction_array)
    arr = PowerTabArray.new
    arr.do_serialize(stream, @chord_text_array)
    arr = PowerTabArray.new
    arr.do_serialize(stream, @rhythslash_array)
    arr = PowerTabArray.new
    arr.do_serialize(stream, @staff_array)
    arr = PowerTabArray.new
    arr.do_serialize(stream, @barline_array)    
    return true    
  end
     
  def do_deserialize(stream)
    read_mfc_rect(stream, @rect)
    @start_bar = Barline.new
    @end_bar = Barline.new
    end_bar = read_byte(stream)
    @position_spacing = read_byte(stream)
    @rhythslash_spacing_above = read_byte(stream)
    @rhythslash_spacing_below = read_byte(stream)
    @extra_spacing = read_byte(stream)
    @end_bar.barline_data(((end_bar & 0x000000e0) >> 5), (end_bar & 0x0000001f))
    @start_bar.do_deserialize(stream)
    arr = PowerTabArray.new
    @direction_array = arr.do_deserialize(stream, Direction.new)
    arr = PowerTabArray.new 
    @chord_text_array = arr.do_deserialize(stream, ChordText.new)
    arr = PowerTabArray.new   
    @rhythslash_array = arr.do_deserialize(stream, RhythmSlash.new)
    arr = PowerTabArray.new
    @staff_array = arr.do_deserialize(stream, Staff.new)
    arr = PowerTabArray.new
    @barline_array = arr.do_deserialize(stream, Barline.new)
  end
     
end
